home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Practical Algorithms for Image Analysis
/
Practical Algorithms for Image Analysis.iso
/
TARFILE.GZ
/
tarfile
/
ch_3.6
/
subsample
/
subsample.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-09-11
|
6KB
|
185 lines
/*
* subsample.c
*
* Practical Algorithms for Image Analysis
*
* Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
*/
/* SUBSAMPLE: program performs image subsampling after low-pass filtering
* usage: subsample inimg outimg [-r subsample rate]
* [-d DEGREE_FILTERING] [-q quickFlag] [-L]
*/
#define DFLT_SUBRATE 2 /* subsample by 2 is default */
#define DFLT_DEG_FLTR 0.5 /* default degree of filtering */
#define RECT_CUTOFF 0.443883 /* factor to calc. 3dB cutoff freq */
#define GAUSS_CUTOFF 0.832555 /* factor to calc. 3dB cutoff freq */
#define ROUNDUP 0.99999 /* for rounding up integer */
#define NORM 1000.0 /* normaliz. factor to integerize */
#include <stdio.h>
#include <stdlib.h>
#include <images.h>
#include <tiffimage.h>
#include <math.h>
#include <string.h>
extern void print_sos_lic ();
long convolve1r (Image *, Image *, long *, long, long);
long smoothr (Image *, Image *, long, long);
long input (int, char **, long *, double *, short *);
long usage (short);
main (argc, argv)
int argc;
char *argv[];
{
Image *imgI, *imgO; /* input, output image structures */
long width, height; /* image size */
double cutoff; /* low-pass cutoff frequency */
long fltrSize; /* filter mask size */
long rSubsample; /* subsample rate */
double degFltr; /* degree of filtering [0.0 - 1.0] */
double stdDev; /* std. deviation param. of Gaussian */
long *fltr; /* 1D filter mask */
long midFltr; /* middle filter coefficient */
short quickFlag; /* for quick and dirty rect. filter */
long i;
if (input (argc, argv, &rSubsample, °Fltr, &quickFlag) < 0)
return (-1);
/* open input image */
imgI = ImageIn (argv[1]);
height = ImageGetHeight (imgI);
width = ImageGetWidth (imgI);
printf ("Input mage size is %dx%d.\n", width, height);
/* determine filter size and coefficients */
if (degFltr == 0.0)
cutoff = 100.0;
else
cutoff = 0.5 / (rSubsample * degFltr);
if (quickFlag) /* rectangular filter window */
fltrSize = (long) (RECT_CUTOFF / cutoff + ROUNDUP);
else { /* Gaussian filter window */
stdDev = GAUSS_CUTOFF / cutoff;
fltrSize = (long) (3.0 / (2.0 * cutoff) + 0.5);
}
if ((fltrSize % 2) == 0)
fltrSize += 1;
printf ("Filter 3dB cutoff frequency is %5.2f and filter size is %dx%d.\n",
cutoff, fltrSize, fltrSize);
if (!quickFlag) {
fltr = (long *) calloc (fltrSize, sizeof (*fltr));
midFltr = fltrSize / 2;
for (i = 0; i <= midFltr; i++)
fltr[i + midFltr] = fltr[midFltr - i]
= (long) (NORM * exp (-i * i / (2.0 * stdDev * stdDev)));
}
/* perform filtering */
imgO = ImageAlloc (height / rSubsample + 1, width / rSubsample + 1, 8);
if (quickFlag)
smoothr (imgI, imgO, fltrSize, rSubsample);
else
convolve1r (imgI, imgO, fltr, fltrSize, rSubsample);
/* output subsampled image */
printf ("Output image size is %dx%d.\n",
width / rSubsample + 1, height / rSubsample + 1);
ImageOut (argv[2], imgO);
return (0);
}
/* USAGE: function gives instructions on usage of program
* usage: usage (flag)
* When flag is 1, the long message is given, 0 gives short.
*/
long
usage (flag)
short flag; /* flag =1 for long message; =0 for short message */
{
/* print short usage message or long */
printf ("USAGE: subsample inimg outimg [-r SAMPLE_RATE <%d>]\n", DFLT_SUBRATE);
printf (" [-d DEG_FILTERING <%3.1f>] [-q] [-L]\n", DFLT_DEG_FLTR);
if (flag == 0)
return (-1);
printf ("\nsubsample performs subsampling after low-pass\n");
printf ("filtering on image; the default filter is a Gaussian\n\n");
printf ("ARGUMENTS:\n");
printf (" inimg: input image filename (TIF)\n");
printf (" outimg: output image filename (TIF)\n\n");
printf ("OPTIONS:\n");
printf (" -r SAMPLE_RATE: rate of image reduction; the default setting\n");
printf (" -r %d reduces rate to reduce image by 2 in x and y).\n", DFLT_SUBRATE);
printf (" -d DEG_FILTERING: value set between 0.0 and 1.0 controlling\n");
printf (" the degree of low-pass filtering; a value\n");
printf (" of 1.0 produces maximum filtering to reduce aliasing,\n");
printf (" but may lead to blurring;\n");
printf (" a value of 0.0 does no filtering at the risk of aliasing.\n");
printf (" the default is %3.1f.\n", DFLT_DEG_FLTR);
printf (" -q: when set, performs quick low-pass filtering \n");
printf (" rectangular filter rather than Gaussian filter;\n");
printf (" the former is faster but doesn't produce equally\n");
printf (" good results as does the latter.\n");
printf (" -L: print Software License for this module\n");
return (-1);
}
/* INPUT: function reads input parameters
* usage: input (argc, argv, &rSubsample,
* °Fltr, &quickFlag)
*/
#define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
long
input (argc, argv, rSubsample, degFltr, quickFlag)
int argc;
char *argv[];
long *rSubsample; /* subsample rate */
double *degFltr; /* degree of filtering [0.0 - 1.0] */
short *quickFlag; /* for quick and dirty rect. filter */
{
long n;
if (argc < 3)
USAGE_EXIT (-1);
*rSubsample = DFLT_SUBRATE;
*degFltr = DFLT_DEG_FLTR;
*quickFlag = 0;
for (n = 3; n < argc; n++) {
if (strcmp (argv[n], "-r") == 0) {
if (++n == argc || argv[n][0] == '-')
USAGE_EXIT (-1);
*rSubsample = atol (argv[n]);
}
else if (strcmp (argv[n], "-d") == 0) {
if (++n == argc || argv[n][0] == '-')
USAGE_EXIT (-1);
*degFltr = atof (argv[n]);
}
else if (strcmp (argv[n], "-q") == 0)
*quickFlag = 1;
else if (strcmp (argv[n], "-L") == 0) {
print_sos_lic ();
exit (0);
}
else
USAGE_EXIT (-1);
}
return (0);
}